Core.form = {
    "validateErrorClass": "inputError",
    /**
     * Executa a validação do input referenciada em "input.data('validateFunction')"
     *
     * @param {object jQuery} input
     * @param {boolean} allowEmpty default true (permite campo vazio)
     * @return {boolean}
     */
    "baseValidate": function(input, allowEmpty) {
        allowEmpty = (!allowEmpty) ? false : true; //default true
        var requiredAction = function(input) {
            if (input.is(':hidden:not(.hasEditor)')) {
                Core.console.debug('Campo oculto obrigatório.', '', Core.console.type.ERROR);
            } else {
                Core.form.setValidateTootip(input, 'Preencher o campo obrigatório.');
            }
        };

        if (!allowEmpty && input.is(":radio,:checkbox")) {
            if (!input.is(':checked')) {
                requiredAction(input);
                return false;
            }
        }

        if (!allowEmpty) {
            if (Core.getValUnmasked(input) === "") {
                requiredAction(input);
                return false;
            }
        }

        if ($.isFunction(input.data('validateFunction'))) {
            if (input.data('validateFunction')(input)) {
                return true;
            } else {
                return false;
            }
        }

        return true;
    },
    /**
     * Validação de elementos de formulário
     *
     * @param mixed
     * @return boolean
     */
    "validate": function(mixed) {
        var retorno = true;
        if (!mixed) {
            mixed = $(':input').not(':disabled,:button,:hidden').add('.hasEditor');
            return this.validate(mixed);
        } else {
            if (isset(mixed.jquery)) {

                if (!mixed.is(':input')) {
                    mixed = mixed.find(':input').not(':disabled,:button,:hidden').add('.hasEditor');
                }


                mixed.each(function() {
                    var input = $(this);
                    Core.form.clearValidateTooltip(input);
//                    Core.form.clearValidateMessages(input);

                    // com .data('validateFunction') e sem ser .required...
                    if (($.isFunction(input.data('validateFunction')) &&
                            ($.trim(input.val()) !== '' && !input.hasClass('required')))) {
                        if (!$(this).data('validateFunction')(input)) {
                            retorno = false;
                        }
                    }
                    // com .required...
                    if (input.hasClass('required')) {
                        if (!Core.form.baseValidate(input, false)) {
                            retorno = false;
                        }
                    }
                });
            } else {
                mixed = $(mixed);
                return this.validate(mixed);
            }
        }

        return retorno;
    },
    /**
     * @param {string | object jQuery} inputs
     * @param {string | Array} content
     * @returns {undefined}
     */
    "setValidateTootip": function(inputs, content)
    {
        try {
            inputs = inputs || "";
            content = Core.isArray(content) ? content.join("<br /><hr />") : content || "";
            if (typeof(content) !== "string") {
                throw new Core.Exception("Core.form.setValidateTootip: passe um conteudo para o tooltip valido.");
            }

            if (typeof(inputs) === "string") {
                inputs = $(inputs);
            }
            if (!isset(inputs.jquery) || !inputs.is(':input')) {
                throw new Core.Exception("Core.form.setValidateTootip: passe um input valido.");
            }
            
            inputs.each(function() {
                
                var elem = $(this);
                var editorElement = '';

                if (elem.hasClass('hasEditor')) {
                    editorElement = elem;
                    var iframe = $('#' + elem.attr('id') + '_ifr');
                    elem = $('.mce-tinymce');
                    
                }

                if (elem.is(':radio,:checkbox')) {
                    elem = elem.parent('div');
                }

                Core.form.setValidateMessages(elem, '');

                elem.addClass(Core.form.validateErrorClass);
                Core.form.setTooltip(elem, content);

                if (!elem.is(":input")) {
                    elem = elem.find(":input");
                }
                var _oldVal = Core.getValUnmasked(elem);

                if (elem.hasClass('ac_input')) {

                    elem.live("change blur click", function() {
                        var _newVal = Core.getValUnmasked($(this));

                        if (!empty(_newVal) && _oldVal !== _newVal) {
                            Core.form.clearValidateTooltip(elem);

                        }
                    });
                } else {

                    elem.one("change blur click", function() {
                        if ($(this).is(":radio,:checkbox")) {
                            Core.form.clearValidateTooltip(elem);

                        } else {
                            var _newVal = Core.getValUnmasked($(this));


                            if (!empty(_newVal) && _oldVal !== _newVal) {
                                Core.form.clearValidateTooltip(elem);

                            }
                        }
                    });
                }
            });
        } catch (e) {
            Core.exceptionHandler(e);
        }
    },
    /**
     * @param container string | object jQuery
     * @return void
     */
    "clearValidateTooltip": function(container) {
        try {
            container = container || $("body");
            if (typeof(container) === "string") {
                container = $(container);
            }
            if (!isset(container.jquery)) {
                throw new Core.Exception("Core.form.clearValidateTooltip: passe um seletor válido ou um objeto jQuery.");
            }

            if (!container.is(':input')) {
                container = container.find(':input');
            }

            container.each(function() {
                var elem = $(this);
                var editorElement = '';
                if (elem.hasClass('hasEditor')) {
                    editorElement = elem;
                    var iframe = $('#' + elem.attr('id') + '_ifr');
                    elem = iframe.parents('.mce-container-body').add(iframe);
                }
                if (elem.is(':radio,:checkbox')) {
                    elem = elem.parent('div');
                }

                elem.removeClass(Core.form.validateErrorClass);

                Core.form.removeTooltip(elem);
                Core.form.clearValidateMessages(elem);
            });
        } catch (e) {
            Core.exceptionHandler(e);
        }
    },
    "setValidateMessages": function(input, content)
    {
        try {
            var form = input.parents("form");

            if (form.length > 0) {
                var validateMessagesContainer = form.find(".validateMessages");
                if (validateMessagesContainer.length === 0) {
                    validateMessagesContainer = $('<div class="validateMessages"></div>').prependTo(form);
                }
                validateMessagesContainer.html(content);

                if (!validateMessagesContainer.hasClass("scrolled")) {
                    $('html,body').animate({scrollTop: validateMessagesContainer.offset().top - 70}, 500);
                    validateMessagesContainer.addClass("scrolled");
                }

            } else {
                throw new Core.Exception("Core.form.setValidateMessages: Sem form para colocar o container de validateMessages");
            }
        } catch (e) {
            Core.exceptionHandler(e);
        }
    },
    "clearValidateMessages": function(input)
    {
        try {
            var form = input.parents("form");
            if (form.length > 0) {
                var validateMessagesContainer = form.find(".validateMessages");
                if (validateMessagesContainer.length > 0) {
                    if (form.find("." + Core.form.validateErrorClass).length === 0) {
                        validateMessagesContainer.remove();
                    }
                }
            } else {
                throw new Core.Exception("Core.form.clearValidateMessages: Sem form para colocar o container de validateMessages");
            }
        } catch (e) {
            Core.exceptionHandler(e);
        }
    },
    /**
     *
     * @param {type} errors
     * @returns {Array}
     */
    "validateErrorHandler": function(errors) {
        var messages = [];
        for (var id in errors) {
            messages = [];
            if (id === "type") {
                continue;
            }
            var input = $("#" + id);
            if (input.length === 0) {
                input = $('[name=' + id + ']');
            }
            if (input.length === 0) {
                throw new Core.Exception('Core.form.validateErrorHandler(): ' + 'Campo não encontrado');
            }
            for (var validator in errors[id]) {
                if (errors[id][validator]) {
                    var errorMessage = new String(errors[id][validator]);
                    errorMessage = errorMessage.replace(id, $("label[for=" + id + "]").text());
                    messages.push(errorMessage);

                }
            }
            Core.form.setValidateTootip(input, messages);
        }

        return messages;
    },
    /**
     * @param {object jQuery} element
     * @param {string} content
     * @returns {undefined}
     */
    "setTooltip": function(element, content)
    {


        element.data('oldTitle', element.attr('title'));

        element.attr('title', content);


        element.tooltip({
            position: {
                my: "center bottom-20",
                at: "center top",
                using: function(position, feedback) {
                    $(this).css(position);
                    $("<div>")
                            .addClass("arrow")
                            .addClass(feedback.vertical)
                            .addClass(feedback.horizontal)
                            .appendTo(this);
                }
            }
        });
    },
    /**
     * @param {object jQuery} element
     * @returns {undefined}
     */
    "removeTooltip": function(element)
    {
//        Core.console.debug(element, '(?) limpa o tooltip de');
        if (element.data('tooltip')) {

//            Core.console.debug(element, 'limpa o tooltip de');
            element.tooltip('destroy');

//            Core.console.debug(element.data('oldTitle'), 'oldtitle');

            var title = '';
            if (element.data('oldTitle')) {
                title = element.data('oldTitle');
            }
            element.attr('title', title);
//            Core.console.debug(element.attr('title'), 'title');

        }
    },
    /**
     * Monta um form com campos ocutos
     *
     * @param {string} id
     * @param {string} url
     * @param {mixed} data
     * @param {string} container
     * @return {object jQuery}
     */
    "mountHiddenForm": function(id, url, data, container)
    {
        container = container || "body";
        var element = $('#' + id);

        if (typeof(url) === "object") {
            var request = new Array();
            request[0] = baseUrl;
            request[1] = isset(url.module) ? url.module : baseRequest.module;
            request[2] = isset(url.controller) ? url.controller : baseRequest.controller;
            request[3] = isset(url.action) ? url.action : baseRequest.action;

            url = request.join("/");
        }

        var formXhtml = '<form action="' + url + '" method="post" id="' + id + '">';
        if (element.length > 0) {
            Core.console.warn("Core.form.mountHiddenForm(): Já existe um elemento com esse id.");
            Core.console.debug($('#' + id));
        }

        element.remove();
        if (typeof(data) === 'object') {
            if (isset(data.jquery)) {
                data.each(function(i, elem) {
                    formXhtml += '<input type="hidden"';
//                    formXhtml += '       id="'+$(this).attr('id')+'"';
                    formXhtml += '       name="' + $(this).attr('name') + '"';
                    formXhtml += '       value="' + $(this).val() + '"';
                    formXhtml += '/>';
                });
            } else {
                var value = '';
                for (var i in data) {
                    if (isset(data.i)) {
                        value = data.i;
                    } else {
                        value = (!isset(data[i])) ? '' : data[i];
                    }
                    if (Core.isArray(value)) {
                        for (var o = 0; o < value.length; o++) {
                            formXhtml += '<input type="hidden"';
                            //                        formXhtml += '       id="'+i+'-'+value+'"';
                            formXhtml += '       name="' + i + '[]"';
                            formXhtml += ' value="' + value[o] + '"';
                            formXhtml += '/>';
                        }
                    } else {
                        value = String(value).replace(/\"/gi, '&quot;');
                        formXhtml += '<input type="hidden"';
                        //                    formXhtml += '       id="'+i+'"';
                        formXhtml += '       name="' + i + '"';
                        formXhtml += ' value="' + value + '"';
                        formXhtml += '/>';
                    }
                }
            }
        }
        formXhtml += '</form>';
        return $(formXhtml).appendTo(container);
    },
    /**
     * mostra a quantidades de caracteres em um TEXTAREA
     *
     * @param {object jQuery} objTextarea
     * @returns {undefined}
     */
    "charCounter": function(objTextarea) {
        if (!objTextarea.is('.noCount')) {
            var size = objTextarea.val().length;
            objTextarea.siblings('small.descriptionBottom').text(sprintf('%s Caracter%s.', size, (size > 1 ? 'es' : '')));
        }
    },
    /**
     * Limita a quantidade dos caracteres de um
     * textarea a partir do atributo maxlenght
     *
     * @param {object jQuery} objTextarea
     * @returns {undefined}
     */
    "textareaLimited": function(objTextarea) {
        var maxlength = parseInt(objTextarea.attr('maxlength'));
        if (maxlength > 0) {
            if (!isNaN(maxlength)) {
                if (objTextarea.val().length > maxlength) {
                    objTextarea.val(objTextarea.val().substr(0, maxlength));
                }
            }
        }
        Core.form.charCounter(objTextarea);
    },
    /**
     * Verifica se o valor do evento é um inteiro
     * 
     * @param {event} e
     * @returns {Boolean}
     */
    "checkIntegerFromEvent": function(e) {
        e = e || window.event;
        var k = e.keyCode || e.which || e.charCode;
        var strCheck = '+-0123456789';
        var keysOk = [
//            0,
            Core.keyCode.BACKSPACE,
            Core.keyCode.TAB,
            Core.keyCode.ENTER,
            Core.keyCode.DOWN,
            Core.keyCode.UP,
            Core.keyCode.LEFT,
            Core.keyCode.RIGHT,
            Core.keyCode.HOME,
            Core.keyCode.END,
            Core.keyCode.DELETE,
            Core.keyCode.DELETE,
            Core.keyCode.PAGE_UP,
            Core.keyCode.PAGE_DOWN,
            Core.keyCode.F1,
            Core.keyCode.F5
        ];
        var key = String.fromCharCode(k);

        if (k === Core.keyCode.DOT) {
            return false;
        }

        if ($.inArray(k, keysOk) > -1) {
            return true;
        }

        console.log(key === '.');

        if (strCheck.indexOf(key) === -1) {
            return false;
        }

        return true;
    },
    /**
     * Força o valor ZERO quando tiver vazio
     * 
     * @param {object jQuery} element
     * @returns {undefined}
     */
    "forceZeroInBlankValue": function(element) {
        if ($.trim(element.val()) === "" || parseInt(element.val(), 10) === 0) {
            element.val('0');
        }
    },
    /**
     * Exibe o inspetor do BoxGrid
     *
     * @return {undefined}
     */
    "toggleBoxGrid": function() {
        var tempo = 0;
        var hBoxGrid = $('.hBoxGrid');
        var vBoxGrid = $('.vBoxGrid');
        var hBox = $('.hBox');
        var vBox = $('.vBox');
        try {
            if ((hBox.length + vBox.length) === 0) {
                throw new Core.Exception('Nenhum baseBox encontrado');
            }
            if (true === $.browser.mozilla || true === $.browser.webkit) {
                tempo = 500;
            }
            if ((hBoxGrid.length + vBoxGrid.length) === 0) {
                hBox.addClass('hBoxGrid', tempo);
                vBox.addClass('vBoxGrid', 500);
            } else {
                hBoxGrid.removeClass('hBoxGrid vBoxGrid', tempo);
                vBoxGrid.removeClass('vBoxGrid hBoxGrid', tempo);
            }
        } catch (e) {
            Core.exceptionHandler(e);
        }
    }

};